package com.ysstech.reportworld.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ysstech.common.annotation.YssLog;
import com.ysstech.common.annotation.YssPermissions;
import com.ysstech.common.controller.BaseController;
import com.ysstech.common.entity.Dicvalue;
import com.ysstech.common.entity.SheetDTO;
import com.ysstech.common.entity.TreeNode;
import com.ysstech.common.enums.YssEnum;
import com.ysstech.common.exception.BusinessException;
import com.ysstech.common.util.DateUtil;
import com.ysstech.common.util.fileutil.FileWriterUtil;
import com.ysstech.common.util.resultutil.RestResult;
import com.ysstech.common.util.resultutil.ResultGenerator;
import com.ysstech.reportworld.entity.Database;
import com.ysstech.reportworld.entity.DatabaseConfig;
import com.ysstech.reportworld.entity.DemandBugInfo;
import com.ysstech.reportworld.enums.ReportWorldEnum;
import com.ysstech.reportworld.enums.ReportWorldFileNameEnum;
import com.ysstech.reportworld.enums.ReportWorldStatusEnum;
import com.ysstech.reportworld.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;


/**
 * <p>
 * 报表世界基础数据信息 前端控制器
 * </p>
 *
 * @author lishuangliang
 * @since 2022-04-28
 */
@Controller
@Slf4j
@Api(tags = "报表世界基础数据管理api")
@RequestMapping("/dataBase")
public class DataBaseController extends BaseController {
    @Autowired
    private ModularService modularService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private ReportService reportService;
    @Autowired
    private DatabaseService databaseService;
    @Autowired
    private DemandBugInfoService demandBugInfoService;
    @Autowired
    private DatabaseConfigService databaseConfigService;

    /**
     * 跳转基础数据信息页面
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database"})
    @ApiOperation(value = "跳转基础数据管理页面")
    @YssLog(module = "基础数据管理", remark = "跳转基础数据管理页面")
    @RequestMapping(value = "/page")
    public String page() throws Exception {
        return "reportworld/dataBase";
    }


    /**
     * 加载报表世界基础数据树信息
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database"})
    @ApiOperation(value = "获取基础数据树信息")
    @YssLog(module = "基础数据管理", remark = "获取基础数据树信息")
    @RequestMapping(value = "/queryDatabaseTree")
    @ResponseBody
    public RestResult queryDatabaseTree() throws Exception {
        return ResultGenerator.getSuccessResult("获取基础数据信息成功！",
                databaseService.queryDatabaseTree());
    }


    @YssPermissions(value = {"reportworld:database"})
    @ApiOperation(value = "获取报表世界基础数据管理页面初始值")
    @YssLog(module = "基础数据管理", remark = "获取报表世界基础数据页面初始值")
    @PostMapping(value = "/init")
    @ResponseBody
    public RestResult init() throws Exception {
        Map<String, Object> map = new HashMap<>();
        // 状态
        List<Dicvalue> listStatus = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_STATUS.getCode());
        map.put("listStatus", listStatus);
        map.put("listStatus2", listStatus);
        // 所属模块
        List<TreeNode> listModular = modularService.queryModularTree();
        map.put("listModular", listModular);
        // 字段所属客户
        List<TreeNode> listCustomer = customerService.queryCustomerTree();
        map.put("listCustomer", listCustomer);
        // 字段所属报表
        List<TreeNode> listReport = reportService.queryReportTree();
        map.put("listReport", listReport);
        // 版本
        List<Dicvalue> listVersion = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_VERSION.getCode());
        map.put("listVersion", listVersion);
        map.put("listVersion2", listVersion);
        // 数据库类型
        List<Dicvalue> listReportDataBaseType = dicValueService.getCacheDicValueList(ReportWorldEnum.REPORT_DATABASE_TYPE.getCode());
        if (!CollectionUtils.isEmpty(listReportDataBaseType)) {
            for (int i = listReportDataBaseType.size() - 1; i >= 0; i--) {
                Dicvalue result = listReportDataBaseType.get(i);
                if ("COMMON".equals(result.getValue())) {
                    listReportDataBaseType.remove(result);
                    break;
                }
            }
            map.put("listReportDataBaseType", listReportDataBaseType);
        }
        // 当前版本的所有需求和BUG
        List<DemandBugInfo> demandBugInfoList = demandBugInfoService.selectByPrimaryByVersion();
        map.put("demandBugInfoList", demandBugInfoList);
        List<TreeNode> list = databaseService.queryDatabaseTree();
        map.put("databaseTree", list);
        return ResultGenerator.getSuccessResult("获取页面初始化信息成功", map);
    }

    /**
     * 获取基础数据页面显示的字段信息
     *
     * @param code
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database"})
    @ApiOperation(value = "获取报表世界基础数据管理对应的表格信息")
    @YssLog(module = "基础数据管理", remark = "获取报表世界基础数据管理对应的表格信息")
    @PostMapping(value = "/getDataBaseColumnNames")
    @ResponseBody
    public RestResult getDataBaseColumnNames(String code) throws Exception {
        if (StringUtils.isBlank(code)) {
            throw new BusinessException("没有获取到对应的基础数据编码信息，请稍后重试！");
        }
        DatabaseConfig databaseConfig = databaseConfigService.selectDatabaseConfig(code);
        if (null == databaseConfig) {
            throw new BusinessException("没有获取到对应的基础数据配置信息，请稍后重试！");
        }
        String json = databaseConfig.getShowColumn();
        if (StringUtils.isBlank(json)) {
            throw new BusinessException(code + "还没有维护对应的字段信息！");
        }
        Map<String, String> mapType = JSON.parseObject(json, LinkedHashMap.class);
        if (CollectionUtils.isEmpty(mapType)) {
            throw new BusinessException(code + "没有获取到维护展示字段信息！");
        }
        Map<String, String> mapTypeNew = new LinkedHashMap<>();
        for (Map.Entry<String, String> entry : mapType.entrySet()) {
            if (null == entry || StringUtils.isBlank(entry.getKey()) || StringUtils.isBlank(entry.getValue())) {
                continue;
            }
            mapTypeNew.put(entry.getKey(), entry.getValue() + "【" + entry.getKey() + "】");
        }
        // 每个基础数据公用的字段 ，id值在页面会隐藏，只显示中文
        mapTypeNew.put("STRMODULAR", "所属模块");
        mapTypeNew.put("STRREPORT", "所属报表");
        mapTypeNew.put("STRCUSTOMER", "所属客户");
        mapTypeNew.put("MODULAR", "所属模块");
        mapTypeNew.put("REPORT", "所属报表");
        mapTypeNew.put("CUSTOMER", "所属客户");
        mapTypeNew.put("RW_DB_VERSION", "版本号");
        mapTypeNew.put("RW_DB_STATUS", "状态");
        mapTypeNew.put("STR_RW_DB_STATUS", "状态");
        mapTypeNew.put("RW_DB_ADD_TIME", "添加时间");
        mapTypeNew.put("RW_DB_ADD_USER", "添加人");
        mapTypeNew.put("RW_DB_EDIT_TIME", "修改时间");
        mapTypeNew.put("RW_DB_EDIT_USER", "修改人");
        mapTypeNew.put("RW_DB_ID", "系统编号");
        return ResultGenerator.getSuccessResult("获取表对应字段信息成功", mapTypeNew);
    }


    /**
     * 获取基础数据表格数据信息
     *
     * @param code
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database"})
    @ApiOperation(value = "获取报表世界基础数据管理对应的表格信息")
    @YssLog(module = "基础数据管理", remark = "获取报表世界基础数据管理对应的表格信息")
    @PostMapping(value = "/getDataBasegrid")
    @ResponseBody
    public RestResult getDataBasegrid(String code, String page, String rows, String queryJson) throws Exception {
        Map<String, Object> map = databaseService.queryDataBaseByCode(code, queryJson, this.getPage(page, rows));
        // 获取对应的配置信息
        DatabaseConfig dataBaseConfig = databaseConfigService.selectDatabaseConfig(code);
        map.put("dataBaseConfig", dataBaseConfig);
        return ResultGenerator.getSuccessResult("获取表对应字段信息成功", map);
    }

    /**
     * 修改数据对应模块，基础数据，报表
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:insert"})
    @ApiOperation(value = "新增报表世界基础数据")
    @YssLog(module = "基础数据管理", remark = "新增报表世界基础数据")
    @PostMapping(value = "/dataBaseInsert")
    @ResponseBody
    public RestResult dataBaseInsert(String code, String queryJson) throws Exception {
        databaseService.dataBaseInsert(code, queryJson);
        return ResultGenerator.getSuccessResult("修改报表世界基础数据成功！");
    }

    /**
     * 修改数据对应模块，基础数据，报表
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:update"})
    @ApiOperation(value = "修改报表世界基础数据标记")
    @YssLog(module = "基础数据管理", remark = "修改报表世界基础数据标记")
    @PostMapping(value = "/dataBaseUpdate")
    @ResponseBody
    public RestResult dataBaseUpdate(String code, String queryJson, String ids) throws Exception {
        databaseService.dataBaseUpdate(code, queryJson, ids);
        return ResultGenerator.getSuccessResult("修改报表世界基础数据成功！");
    }

    /**
     * 批量修改
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:batchUpdate"})
    @ApiOperation(value = "修改报表世界基础数据标记")
    @YssLog(module = "基础数据管理", remark = "修改报表世界基础数据标记")
    @PostMapping(value = "/dataBaseBatchUpdate")
    @ResponseBody
    public RestResult dataBaseBatchUpdate(String code, String queryJson, String ids) throws Exception {
        databaseService.dataBaseUpdate(code, queryJson, ids);
        return ResultGenerator.getSuccessResult("修改报表世界基础数据成功！");
    }

    /**
     * 删除对应的数据
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:del"})
    @ApiOperation(value = "删除报表世界基础数据标记")
    @YssLog(module = "基础数据管理", remark = "删除报表世界基础数据标记")
    @PostMapping(value = "/deleteDataBase")
    @ResponseBody
    public RestResult deleteDataBase(String delJson) throws Exception {
        databaseService.deleteDataBase(delJson);
        return ResultGenerator.getSuccessResult("删除报表世界基础数据成功！");
    }

    /**
     * 从文件获取基础数据到库里
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:readFile"})
    @ApiOperation(value = "从文件获取基础数据到库里")
    @YssLog(module = "基础数据管理", remark = "从文件获取基础数据到库里")
    @PostMapping(value = "/dataBaseReadFile")
    @ResponseBody
    public RestResult dataBaseReadFile(MultipartFile multipartfile) throws Exception {
        String msg = databaseService.dataBaseReadFile(multipartfile);
        return ResultGenerator.getSuccessResult(msg);
    }

    /**
     * 获取数据库表的 字段和对应的类型
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:execl"})
    @ApiOperation(value = "导出基础数据EXECL文件")
    @YssLog(module = "基础数据管理", remark = "导出基础数据EXECL文件")
    @PostMapping(value = "/dataBaseExecl")
    @ResponseBody
    public void dataBaseExecl(HttpServletResponse response, String queryJson, String code) throws Exception {
        List<Map<String, Object>> list = databaseService.dataBaseExecl(queryJson, code);
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("没有获取到要导出的数据，请检出数据信息！");
        }
        FileWriterUtil.excelExport(null, code.replace("RW_DB_", ""), list, YssEnum.YSS_XLSX.getCode(), response);
    }

    /**
     * 导出SQl文件
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:sql"})
    @ApiOperation(value = "导出基础数据SQL文件")
    @YssLog(module = "基础数据管理", remark = "导出基础数据SQL文件")
    @PostMapping(value = "/dataBaseSql")
    @ResponseBody
    public void dataBaseSql(HttpServletResponse response, String queryJson, String code) throws Exception {
        String sql = databaseService.dataBaseSql(queryJson, code);
        if (StringUtils.isBlank(sql)) {
            throw new BusinessException("没有对应的数据生成SQL文件，请检出数据信息！");
        }
        FileWriterUtil.downloadFileBuffer(response, sql, code.replace("RW_DB_", ""), ReportWorldFileNameEnum.DATABASE_SQL.getDesc());
    }

    /**
     * 新增基础数据的方法
     *
     * @param database
     * @return
     */
    @YssPermissions(value = {"reportworld:database:database:add"})
    @ApiOperation(value = "新增基础数据信息")
    @YssLog(module = "基础数据管理", remark = "新增基础数据信息")
    @RequestMapping(value = "/add")
    @ResponseBody
    public RestResult add(Database database) throws Exception {
        database.setId(DateUtil.generateUUID());
        database.setAddTime(LocalDateTime.now());
        database.setStatus(ReportWorldStatusEnum.REPORT_NORMAL.getCode());
        database.setAddUser(redisCacheManager.getLoginUserInfo().getLoginId());
        database.setAddTime(LocalDateTime.now());
        databaseService.save(database);
        return ResultGenerator.getSuccessResult("新增基础数据信息成功！");
    }

    /**
     * 查询基础数据的方法
     *
     * @param id
     * @return
     */
    @YssPermissions(value = {"reportworld:database"})
    @ApiOperation(value = "查询基础数据信息")
    @YssLog(module = "基础数据管理", remark = "查询基础数据信息")
    @RequestMapping(value = "/queryDataBaseInfo")
    @ResponseBody
    public RestResult queryDataBaseInfo(String id) throws Exception {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取基础数据信息失败，请稍后重试！");
        }
        QueryWrapper<Database> wrapper = new QueryWrapper<>();
        wrapper.in("ID", id);
        return ResultGenerator.getSuccessResult("获取基础数据信息成功！", databaseService.getOne(wrapper));
    }

    /**
     * 修改基础数据信息
     *
     * @param database
     * @return
     */
    @YssPermissions(value = {"reportworld:database:database:edit"})
    @ApiOperation(value = "修改基础数据信息")
    @YssLog(module = "基础数据管理", remark = "修改基础数据信息")
    @RequestMapping(value = "/edit")
    @ResponseBody
    public RestResult edit(Database database) throws Exception {
        if (database == null || StringUtils.isBlank(database.getId())) {
            throw new BusinessException("获取基础数据信息失败，请稍后重试！");
        }
        database.setEditUser(redisCacheManager.getLoginUserInfo().getLoginId());
        database.setEditTime(LocalDateTime.now());
        databaseService.updateById(database);
        return ResultGenerator.getSuccessResult("修改基础数据信息成功！");
    }

    /**
     * 删除基础数据信息
     *
     * @return
     */
    @YssPermissions(value = {"reportworld:database:database:del"})
    @ApiOperation(value = "删除基础数据信息")
    @YssLog(module = "基础数据管理", remark = "删除基础数据信息")
    @RequestMapping(value = "/del")
    @ResponseBody
    public RestResult delete(String id) throws Exception {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("获取删除基础数据信息失败，请稍后重试！");
        }
        List<String> ids = databaseService.queryDatabaseIds(id);
        databaseService.removeByIds(ids);
        // 删除对应配置信息
        QueryWrapper<DatabaseConfig> wrapperConfig = new QueryWrapper<>();
        wrapperConfig.in("DATABASE_ID", ids);
        databaseConfigService.remove(wrapperConfig);
        return ResultGenerator.getSuccessResult("删除基础数据信息成功！");
    }


    /**
     * 基础数据的配置管理
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:manager"})
    @ApiOperation(value = "基础数据配置管理")
    @YssLog(module = "基础数据管理", remark = "基础数据配置管理")
    @PostMapping(value = "/dataBaseManager")
    @ResponseBody
    public RestResult dataBaseManager(String code) throws Exception {
        Map<String, Object> map = databaseConfigService.dataBaseManager(code);
        return ResultGenerator.getSuccessResult("获取报表世界基础数据配置信息成功！", map);
    }


    /**
     * 保存基础数据的配置管理
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:manager"})
    @ApiOperation(value = "保存基础数据配置管理")
    @YssLog(module = "基础数据管理", remark = "基保存础数据配置管理")
    @PostMapping(value = "/saveDataBaseConfig")
    @ResponseBody
    public RestResult saveDataBaseConfig(DatabaseConfig databaseConfig) throws Exception {
        databaseConfigService.saveDataBaseConfig(databaseConfig);
        return ResultGenerator.getSuccessResult("保存报表世界基础数据配置信息成功！");
    }

    /**
     * 更新校验语句
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:check"})
    @ApiOperation(value = "更新基础数据校验语句")
    @YssLog(module = "基础数据管理", remark = "更新基础数据校验语句")
    @PostMapping(value = "/updateCheckDataBase")
    @ResponseBody
    public RestResult updateCheckDataBase() throws Exception {
        databaseService.updateCheckDataBase();
        return ResultGenerator.getSuccessResult("更新基础数据校验语句信息成功！");
    }

    /**
     * 导出校验结果文件
     *
     * @return
     * @throws Exception
     */
    @YssPermissions(value = {"reportworld:database:check:file"})
    @ApiOperation(value = "导出基础数据校验结果")
    @YssLog(module = "基础数据管理", remark = "导出基础数据校验结果")
    @PostMapping(value = "/queryCheckDataBaseInfoAll")
    @ResponseBody
    public void queryCheckDataBaseInfoAll(HttpServletResponse response) throws Exception {
        String msgInfo = databaseService.queryCheckDataBaseInfoAll();
        FileWriterUtil.downloadFileBuffer(response, msgInfo, "校验结果信息", ".txt");
    }

}
